package cn.itcast.bos.realm;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.itcast.bos.domain.system.Permission;
import cn.itcast.bos.domain.system.Role;
import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.action.teke_delivary.PermissionService;
import cn.itcast.bos.service.action.teke_delivary.RoleService;
import cn.itcast.bos.service.action.teke_delivary.UserService;

///@Service("bosRealm")
// 自定义多的 Realm 在这里实现 控制器 和 数据的连接 通过 Spring 的注解扫描 来实现 SumAnager..核心管理器的 连接 得以实现
// Realm 的 作为 核心滚利器和安全数据之间的连接器
public class BosRealm extends AuthorizingRealm {

	// 注入Service
	@Autowired
	private UserService userService;

	@Autowired
	private RoleService roleService;

	@Autowired
	private PermissionService permissionService;

	// 进行授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
		System.out.println("shiro...授权管理.....");
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		Subject subject = SecurityUtils.getSubject(); // 通过工具获取 到Action中的内容数据
		User user = (User) subject.getPrincipal();
		// 调用业务层 查询角色
		List<Role> roles = roleService.findByUser(user);
		for (Role role : roles) {
			authorizationInfo.addRole(role.getKeyword());
		}
		// 调用业务层 进行权限查询
		List<Permission> permissions = permissionService.findByUser(user);
		for (Permission permission : permissions) {
			authorizationInfo.addRole(permission.getKeyword());
		}
		return authorizationInfo;

	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		System.out.println("shiro...认证管理......");
		// 获取用户名密码 抓换 token
		UsernamePasswordToken usernamepasswordToken = (UsernamePasswordToken) token;
		// 根据用户名 查询用户信息 先对用户名进行判断 判断用户名存不存在
		User user = userService.findByUsername(usernamepasswordToken.getUsername());

		if (user == null) {
			// 用户名不存在
			// 参数一：期望登陆后 保存在Subject中
			// 参数二： 如果返回为 null 用户不存在 则返回用户名
			// 参数三： realm 名称
			return null;
		} else {
			// 用户名存在
			// 当返回用户名密码时 securityManager 安全管理器 自动比较返回 密码和用户输入密码是否一致
			// 如果 密码 一致 ， 登录成功 不一致 报出密码错误异常
			// getName() ----获取的是什么？？
			return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
		}

	}

}
